
#include <sys_config.h>
#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/alloc.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>
#include <hld/hld_dev.h>
#include <hld/crypto/crypto.h>



#ifdef DUAL_ENABLE
#include <modules.h>

#define offsetof(type, f) ((unsigned long) \
((char *)&((type *)0)->f - (char *)(type *)0))

enum HLD_CE_FUNC{

    FUNC_CE_OPEN = 0,
    FUNC_CE_CLOSE,
    FUNC_CE_GENERATE,
    FUNC_CE_LOAD,
    FUNC_CE_IOCTL,
    FUNC_CE_KEY_GENERATE_TWO_DES,
    FUNC_CE_KEY_GENERATE_TWO_AES,
    FUNC_CE_GENERATE_CW_KEY,
    FUNC_CE_GENERATE_SINGLE_LEVEL_KEY 
};

#ifndef _HLD_CRYPTO_REMOTE



UINT32 hld_ce_entry[] = 
{
    (UINT32)ce_open,
    (UINT32)ce_close,
    (UINT32)ce_key_generate,
    (UINT32)ce_key_load,
    (UINT32)ce_ioctl,
    (UINT32)ce_des_key_generate_two_level,
    (UINT32)ce_aes_key_generate_two_level,
    (UINT32)ce_generate_cw_key,
    (UINT32)ce_generate_single_level_key
};



void hld_crypto_callee(UINT8 *msg)
{
    
    OS_hld_callee(hld_ce_entry, msg);
}
#endif  /*_HLD_CE_REMOTE*/

#ifdef _HLD_CRYPTO_REMOTE

#define CE_NPARA(x) ((HLD_CRYPTO_MODULE<<24)|(x<<16))

UINT32 ce_io_control[] = 
{ //desc of pointer para
  1, DESC_STATIC_STRU(0, 0),
  1, DESC_P_PARA(0, 2, 0), 
  //desc of pointer ret
  0,                          
  0,
};
RET_CODE ce_open(pCE_DEVICE pCeDev)
{
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(1)|FUNC_CE_OPEN, NULL);
}

RET_CODE ce_close(pCE_DEVICE pCeDev)
{
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(1)|FUNC_CE_CLOSE, NULL);
}
RET_CODE ce_key_generate(pCE_DEVICE pCeDev,pCE_DATA_INFO pCe_data_info)
{
    UINT32 desc[] = 
    { //desc of pointer para
      1, DESC_STATIC_STRU(0, sizeof(CE_DATA_INFO)),
      1, DESC_P_PARA(0, 1, 0),
      //desc of pointer ret
      0,                          
      0,
    };
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(2)|FUNC_CE_GENERATE, desc);
}

RET_CODE ce_key_load(pCE_DEVICE pCeDev,pOTP_PARAM pCe_opt_info)
{
    UINT32 desc[] = 
    { //desc of pointer para
      1, DESC_STATIC_STRU(0, sizeof(OTP_PARAM)),
      1, DESC_P_PARA(0, 1, 0),
      //desc of pointer ret
      0,                          
      0,
    };
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(2)|FUNC_CE_LOAD, desc);
}

RET_CODE ce_des_key_generate_two_level(pCE_DEVICE pCeDev,pCE_DATA_INFO pCe_data_info_one1,
                            pCE_DATA_INFO pCe_data_info_one2,pCE_DATA_INFO pCe_data_info_two)
{
    UINT32 desc[] = 
    { //desc of pointer para
      3, DESC_STATIC_STRU(0, sizeof(CE_DATA_INFO)),DESC_STATIC_STRU(0, sizeof(CE_DATA_INFO)),DESC_STATIC_STRU(0, sizeof(CE_DATA_INFO)),
      3, DESC_P_PARA(0, 1, 0),DESC_P_PARA(0, 2, 1),DESC_P_PARA(0, 3, 2),
      //desc of pointer ret
      0,                          
      0,
    };
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(4)|FUNC_CE_KEY_GENERATE_TWO_DES, desc);
}

RET_CODE ce_aes_key_generate_two_level(pCE_DEVICE pCeDev,pCE_DATA_INFO pCe_data_info_one,
            pCE_DATA_INFO pCe_data_info_two)
{
    UINT32 desc[] = 
    { //desc of pointer para
      2, DESC_STATIC_STRU(0, sizeof(CE_DATA_INFO)),DESC_STATIC_STRU(0, sizeof(CE_DATA_INFO)),
      2, DESC_P_PARA(0, 1, 0),DESC_P_PARA(0, 2, 1),
      //desc of pointer ret
      0,                          
      0,
    };
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(3)|FUNC_CE_KEY_GENERATE_TWO_AES, desc);
}

RET_CODE ce_ioctl(pCE_DEVICE pCeDev,UINT32 cmd,UINT32 param)
{
    UINT32 i;
    UINT32 common_desc[sizeof(ce_io_control)];
    UINT32 *desc = (UINT32 *)common_desc;
    UINT32 *b = (UINT32 *)ce_io_control;
    
    for(i = 0; i < sizeof(ce_io_control)/sizeof(UINT32); i++)
    {
        desc[i] = b[i];
    }
    switch (cmd)
    {
        case IO_OTP_ROOT_KEY_GET:
            DESC_STATIC_STRU_SET_SIZE(common_desc, 0, sizeof(OTP_PARAM));
        break;

        case IO_CRYPT_DATA_INPUT:
            DESC_STATIC_STRU_SET_SIZE(common_desc, 0, sizeof(DATA_PARAM));
        break;

        case IO_CRYPT_PARAM_SET:
            DESC_STATIC_STRU_SET_SIZE(common_desc, 0, sizeof(DES_PARAM));
        break;

        case IO_CRYPT_SECOND_KEY_CONFIG:
           DESC_STATIC_STRU_SET_SIZE(common_desc, 0, sizeof(CE_KEY_PARAM));    	
        break;

        case IO_SECOND_KEY_GENERATE:
            desc = NULL ;
        break;

        case IO_CRYPT_DEBUG_GET_KEY:
            DESC_OUTPUT_STRU_SET_SIZE(common_desc, 0, sizeof(CE_DEBUG_KEY_INFO)); 
            break;
        case IO_CRYPT_POS_IS_OCCUPY:
        {  
            DESC_OUTPUT_STRU_SET_SIZE(common_desc, 0, sizeof(CE_POS_STS_PARAM));  
        }
        break;
        case IO_CRYPT_POS_SET_USED:
        {
            desc=NULL;
        }
        break;
        case IO_CRYPT_POS_SET_IDLE:
        {           
            desc=NULL;
        }
        break;
        case IO_CRYPT_FOUND_FREE_POS:
        {
            DESC_OUTPUT_STRU_SET_SIZE(common_desc, 0, sizeof(CE_FOUND_FREE_POS_PARAM));
        }
        break;
        case IO_DECRYPT_PVR_USER_KEY:
        {
            DESC_STATIC_STRU_SET_SIZE(common_desc, 0, sizeof(CE_PVR_KEY_PARAM));
        }
        break;
        default:
            SDBBP();
        break;
        
    }
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(3)|FUNC_CE_IOCTL, desc);
}

RET_CODE ce_generate_cw_key(const UINT8 *in_cw_data,UINT8 mode,UINT8 first_pos,UINT8 second_pos)
{
     UINT32 desc[] = 
    { //desc of pointer para
      1, DESC_STATIC_STRU(0, 16),
      1, DESC_P_PARA(0, 0, 0),
      //desc of pointer ret
      0,                          
      0,
    }; 
    jump_to_func(NULL, OS_hld_caller, in_cw_data, CE_NPARA(4)|FUNC_CE_GENERATE_CW_KEY, desc);
}

RET_CODE ce_generate_single_level_key(pCE_DEVICE pCeDev,pCE_DATA_INFO pCe_data_info)
{
    UINT32 desc[] = 
    { //desc of pointer para
      1, DESC_STATIC_STRU(0, sizeof(CE_DATA_INFO)),
      1, DESC_P_PARA(0, 1, 0),
      //desc of pointer ret
      0,                          
      0,
    };
    jump_to_func(NULL, OS_hld_caller, pCeDev, CE_NPARA(2)|FUNC_CE_GENERATE_SINGLE_LEVEL_KEY, desc);
}
#endif  /*_HLD_CE_REMOTE*/

#endif  /*DUAL_ENABLE*/

